package com.hky.algorithm.mahjongGame;

import com.hky.algorithm.realize.Type;

import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 对局服务类，创建步骤：
 * 1 new GameService(roomId);
 * 2 addGamePlayer(player);
 * 3 initGame();
 */
public class GameService {
    // 对局数据
    public GameData gameData = new GameData();

    // 房间号
    public int roomId;

    // 已经开始游戏
    public boolean alreadyStart;

    // 有一个玩家出牌时，可以胡的人数，-1为没有人要胡
    public AtomicInteger canHuNum = new AtomicInteger(-1);

    // 有一个玩家出牌时并且有人可以胡时，保存下一个摸牌玩家顺序，-1为初始值
    public Integer nextPlayerOrder = -1;

    /**
     * 当前出牌玩家的次序
     */
    public Integer outCardPlayerOrder;


    public GameService(int roomId) {
        this.roomId = roomId;
    }

    /**
     * 添加玩家
     *
     * @param player 玩家
     */
    public void addGamePlayer(GamePlayer player) {
        gameData.addPlayer(player);
    }


    /**
     * 获取一个玩家
     *
     * @param sessionId 玩家客户端id
     * @return 玩家
     */
    public GamePlayer getPlayerBySessionId(String sessionId) {
        return gameData.getPlayerBySessionId(sessionId);
    }

    /**
     * 初始化对局数据
     */
    public void initGameService() {
        alreadyStart = false;
        canHuNum.set(-1);
        nextPlayerOrder = -1;
        gameData.initGameData();
    }


    /**
     * 计算对手的危险牌
     *
     * @return 危险牌集合
     */
    public Set<Card> calRivalDanger(GamePlayer player) {
        player.calRivalDanger();
        return player.collectDanger(player.game);
    }

    /**
     * 计算自己要胡的牌
     *
     * @return 危险牌集合
     */
    public Set<Card> calSelfDanger(GamePlayer player) {
        player.calSelfDanger();
        return player.collectDanger(player.selfGame);
    }

    /**
     * 定缺
     *
     * @param player 定缺的玩家
     * @param type 定缺的牌
     */
    public void defineLack(GamePlayer player, Type type) {
        gameData.defineLack(player, type);
    }

    /**
     * 自己打了一张牌
     */
    public void outCardSelf(GamePlayer player, Card card) {
        player.outCardSelf(card, 1);
        // 更新对手的手牌
        outCardRival(player, card, 1);
    }

    /**
     * 发一张牌给玩家
     */
    public Card distributeCard(GamePlayer player) {
        return gameData.distributeCard(player);
    }

    /**
     * 自己要胡
     *
     * @param player 玩家自己
     */
    public void huSelf(GamePlayer player, Card card) {
        player.huCard = card;
        player.alreadyHu = true;
    }

    /**
     * 自己要碰或者杠
     */
    public void pengOrGang(GamePlayer player, GangItem gangItem) {
        gameData.pengOrGang(player, gangItem);
    }

    /**
     * 对手出了一张牌
     * @param player 对手
     * @param card 牌
     * @param num 数量
     */
    public void outCardRival(GamePlayer player, Card card, int num) {
        gameData.outCardRival(player, card, num);
    }

    /**
     * 判断对局是否结束
     *
     * @return true false : 结束 没结束
     */
    public boolean gameOver() {
        if (gameData.leftCards.size() == 0) return true;
        int n = 0;
        for (GamePlayer player : gameData.players) {
            if (player.alreadyHu) n++;
        }
        return n >= gameData.players.size() - 1;
    }
}
